﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace GameLoop
{   ///<summary>
    /// Implements a precise timer that 
    /// will be used to smootly render the
    /// game content independent on the 
    /// PC CPU power and tackt. 
    ///</summary>
    public class PreciseTimer
    {    ///<summary>
        ///Tells the .NET that it is 
        ///non managed C code that is executed.
        ///</summary>
        [System.Security.SuppressUnmanagedCodeSecurity]
        ///<summary>
        ///The library where the C function is defined.
        ///</summary>
        [DllImport("kernel32")]
        ///<summary>
        ///The QueryPerformanceFrequency function retrieves 
        ///the frequency of the high-resolution performance counter. 
        ///Most modern hardware has a high-resolution timer; 
        ///this function is used to get the frequency 
        ///at which the timerincrements.
        ///</summary>
        private static extern bool QueryPerformanceFrequency(ref long PerformanceFrequency);
        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("kernel32")]
        ///<summary>
        ///The QueryPerformanceCounter function retrieves 
        ///the currentvalue of the high-resolution 
        ///performance counter. These can be used together 
        ///totime how long the last frame took.
        ///</summary>
        private static extern bool QueryPerformanceCounter(ref long PerformanceCount);
        long _ticksPerSecond = 0;
        long _previousElapsedTime = 0;
        ///<summary>
        ///Consturctor that initially executes the 
        ///QueryPerformanceFrequency method to fill the ticksPerSecond
        ///variable used for devision of the timer. 
        ///</summary>
        public PreciseTimer()
        {
            QueryPerformanceFrequency(ref _ticksPerSecond);
            GetElapsedTime(); // Get rid of first rubbish result
        }
        ///<summary>
        ///Calculates the elapsed time for game rendering on this 
        ///CPU. 
        ///</summary>
        public double GetElapsedTime()
        {
            long time = 0;
            QueryPerformanceCounter(ref time);
            double elapsedTime = (double)(time - _previousElapsedTime) / (double)_ticksPerSecond;
            _previousElapsedTime = time;
            return elapsedTime;
        }
    }
}

